<template><div><h2 id="知识点" tabindex="-1"><a class="header-anchor" href="#知识点"><span>知识点</span></a></h2>
<h3 id="sql语句组成部分以及执行顺序" tabindex="-1"><a class="header-anchor" href="#sql语句组成部分以及执行顺序"><span>SQL语句组成部分以及执行顺序</span></a></h3>
<p>MySQL的SQL增删改查四类SQL语句分别有哪些组成部分，各成分的执行顺序分别是什么样的（当年数据库系统课上学的那些东西，落到MySQL中的实践）</p>
<ol>
<li>INSERT
<ol>
<li>INSERT INTO 确定要插入的表</li>
<li>VALUES 插入指定字段</li>
</ol>
</li>
<li>DELETE
<ol>
<li>FROM 确定要查询的表</li>
<li>WHERE 过滤掉不满足的行</li>
</ol>
</li>
<li>UPDATE
<ol>
<li>UPDATE  指定要更新的表名</li>
<li>WHERE 过滤掉不满足的行</li>
<li>SET 更新指定的字段</li>
</ol>
</li>
<li>SELECT
<ol>
<li>FROM（， JOIN） 先确定要查询的表，如果是（，）则多表之间进行笛卡尔积，如果是（JOIN）则进行表连接</li>
<li>WHERE 过滤掉不满足的行</li>
<li>GROUP BY 对筛选结果进行分组</li>
<li>HAVING 对分组结果进行筛选</li>
<li>DISTINCT 去除重复行</li>
<li>ORDER BY 排序</li>
<li>LIMIT 扫描指定行数在丢弃</li>
<li>SELECT 返回要返回的列</li>
</ol>
</li>
</ol>
<h3 id="客户端发送sql到mysql经历了什么" tabindex="-1"><a class="header-anchor" href="#客户端发送sql到mysql经历了什么"><span>客户端发送SQL到MySQL经历了什么？</span></a></h3>
<p>MySQL数据库的SQL从Java 的connection，到返回结果，中间分别有哪些工序，这些工序分别做了哪些操作</p>
<ol>
<li><em>建立连接。客户端与Mysql建立TCP连接</em></li>
<li><em>查询缓存。将客户端发送的SQL语句从Mysql的查询缓存查找（Key是SQl，Value是结果）如果缓存命中，则直接返回结果，未命中则继续执行（8.0移除了查询缓存）</em></li>
<li><em>解析SQL。先进行词法分析，识别出所有的关键字，在进行语法分析，根据语法规则判断是否满足Mysql语法，满足则构建SQl语法树，不满足则直接报错</em></li>
<li><em>执行SQL。会经历三个阶段 预处理-&gt;优化-&gt; 执行 ，预处理主要是查看SQL语句中的表，字段是否存在，如果不存在，则报错。优化主要是选择使用表中的那个索引（没有索引则进行全表扫描）并生成执行计划，最后，执行就是执行器与存储引擎进行交互（个人理解，也就是执行器指挥存储引擎进行IO操作）</em></li>
</ol>
<blockquote>
<p><a href="https://www.xiaolincoding.com/mysql/base/how_select.html#mysql-%E6%89%A7%E8%A1%8C%E6%B5%81%E7%A8%8B%E6%98%AF%E6%80%8E%E6%A0%B7%E7%9A%84" target="_blank" rel="noopener noreferrer">执行一条 select 语句，期间发生了什么？ | 小林coding</a></p>
</blockquote>
<h3 id="mysql的执行计划explain-如何查看-explain-返回的各字段是什么含义" tabindex="-1"><a class="header-anchor" href="#mysql的执行计划explain-如何查看-explain-返回的各字段是什么含义"><span>MySQL的执行计划EXPLAIN 如何查看，EXPLAIN 返回的各字段是什么含义</span></a></h3>
<p>使用explain + SQL 就可以查看这条SQL的执行计划。</p>
<p>执行计划各字段</p>
<ol>
<li>id 表示执行顺序，数字越大越先执行，如果是null则表示结果集</li>
<li>select_type  查询的类型，主要是用于区分普通查询、联合查询、子查询等复杂的查询</li>
<li>table 显示的查询表名</li>
<li>type MySQL的官网解释为：连接类型(the join type)。它描述了找到所需数据使用的扫描方式。</li>
<li>possible_keys 所有的索引</li>
<li>key 实际使用的索引，如果为NULL，则没有使用索引。</li>
<li>key_len  用于处理查询的索引长度</li>
<li>ref 如果是使用的常数等值查询，这里会显示const，如果是连接查询，被驱动表的执行计划这里会显示驱动表的关联字段，如果是条件使用了表达式或者函数，或者条件列发生了内部隐式转换，这里可能显示为func</li>
<li>rows 读取的行数</li>
<li>fitered 通过条件过滤出的行数的百分比估计值。</li>
<li>Extra  MYSQL 如何解析查询的额外信息</li>
</ol>
<blockquote>
<p><a href="https://blog.csdn.net/qq_37493556/article/details/107009047" target="_blank" rel="noopener noreferrer">如何查看MySQL执行计划（Explain）_mysql explain怎么看-CSDN博客</a></p>
<p><a href="https://blog.csdn.net/zhouhengzhe/article/details/112272134" target="_blank" rel="noopener noreferrer">MySQL—— MySQL的执行计划详解（Explain）_mysql执行过程expla-CSDN博客</a></p>
</blockquote>
<h3 id="补充" tabindex="-1"><a class="header-anchor" href="#补充"><span>补充</span></a></h3>
<p>如何查看SQL各部分执行时间</p>
<div class="language-sql line-numbers-mode" data-highlighter="shiki" data-ext="sql" style="background-color:#282c34;color:#abb2bf"><pre class="shiki one-dark-pro vp-code" v-pre=""><code><span class="line"><span style="color:#7F848E;font-style:italic">-- 开启 PROFILING 功能</span></span>
<span class="line"><span style="color:#C678DD">SET</span><span style="color:#ABB2BF"> profiling </span><span style="color:#56B6C2">=</span><span style="color:#D19A66"> 1</span><span style="color:#ABB2BF">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#7F848E;font-style:italic">-- 执行查询语句</span></span>
<span class="line"><span style="color:#C678DD">SELECT</span><span style="color:#ABB2BF"> id,a,b,c,d </span><span style="color:#C678DD">from</span><span style="color:#ABB2BF"> test_table </span><span style="color:#C678DD">where</span><span style="color:#ABB2BF"> id</span><span style="color:#56B6C2">></span><span style="color:#D19A66">997999</span><span style="color:#C678DD"> LIMIT</span><span style="color:#D19A66"> 1</span><span style="color:#ABB2BF">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#7F848E;font-style:italic">-- 查询执行计划每一阶段的时间信息</span></span>
<span class="line"><span style="color:#C678DD">SELECT</span><span style="color:#C678DD"> state</span><span style="color:#ABB2BF">, </span><span style="color:#56B6C2">SUM</span><span style="color:#ABB2BF">(duration) </span><span style="color:#C678DD">AS</span><span style="color:#ABB2BF"> total_duration</span></span>
<span class="line"><span style="color:#C678DD">FROM</span><span style="color:#D19A66"> information_schema</span><span style="color:#ABB2BF">.</span><span style="color:#D19A66">PROFILING</span></span>
<span class="line"><span style="color:#C678DD">GROUP BY</span><span style="color:#C678DD"> state</span></span>
<span class="line"><span style="color:#C678DD">ORDER BY</span><span style="color:#ABB2BF"> total_duration </span><span style="color:#C678DD">DESC</span><span style="color:#ABB2BF">;</span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="实验" tabindex="-1"><a class="header-anchor" href="#实验"><span>实验</span></a></h2>
<p>建一个表里有主键ID和A~D 共5个字段
id 顺序数字id<br>
其中A为varchar(64) 生成随机字符<br>
其中B为int 生成随机数字<br>
其中C为BigInt 生成随机数字<br>
其中D为LongText 生成1KB左右随机字符</p>
<p>初始生成100W行，不要创建索引，这是为了你了解SQL</p>
<p><strong>在Java中完成以下SQL</strong></p>
<ol>
<li>查询第99w8000行的数据，如果慢，通过执行计划分析为什么慢，如果同样的SQL执行变快，分析为什么又快了，提出低毫秒级的优化方案</li>
</ol>
<div class="language-sql line-numbers-mode" data-highlighter="shiki" data-ext="sql" style="background-color:#282c34;color:#abb2bf"><pre class="shiki one-dark-pro vp-code" v-pre=""><code><span class="line"><span style="color:#C678DD">SELECT</span><span style="color:#ABB2BF"> id,a,b,c,d </span><span style="color:#C678DD">from</span><span style="color:#ABB2BF"> test_table </span><span style="color:#C678DD">LIMIT</span><span style="color:#D19A66"> 997999</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">; # 时间太长</span></span>
<span class="line"><span style="color:#C678DD">SELECT</span><span style="color:#ABB2BF"> id,a,b,c,d </span><span style="color:#C678DD">from</span><span style="color:#ABB2BF"> test_table </span><span style="color:#C678DD">ORDER BY</span><span style="color:#ABB2BF"> id </span><span style="color:#C678DD">LIMIT</span><span style="color:#D19A66"> 997999</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">; # 走索引稍微快一点</span></span>
<span class="line"><span style="color:#C678DD">SELECT</span><span style="color:#ABB2BF"> id,a,b,c,d </span><span style="color:#C678DD">from</span><span style="color:#ABB2BF"> test_table </span><span style="color:#C678DD">where</span><span style="color:#ABB2BF"> id</span><span style="color:#56B6C2">></span><span style="color:#D19A66">997999</span><span style="color:#C678DD"> LIMIT</span><span style="color:#D19A66"> 1</span><span style="color:#ABB2BF">; # 如果id连续,降低扫描行数</span></span>
<span class="line"><span style="color:#C678DD">SELECT</span><span style="color:#ABB2BF"> id,a,b,c,d </span><span style="color:#C678DD">from</span><span style="color:#ABB2BF"> test_table </span><span style="color:#C678DD">where</span><span style="color:#ABB2BF"> id  </span><span style="color:#56B6C2">=</span><span style="color:#ABB2BF"> (</span><span style="color:#C678DD">select</span><span style="color:#ABB2BF"> id </span><span style="color:#C678DD">from</span><span style="color:#ABB2BF"> test_table </span><span style="color:#C678DD">limit</span><span style="color:#D19A66"> 997999</span><span style="color:#ABB2BF">,</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">); # 如果id不连续，则可以使用id（用了索引主键索引）进行筛选，减少其他字段的提取（减少了部分时间）最后在回表。</span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><ol start="2">
<li>根据B的数字范围筛选出某一区间前100个数字，根据C的数字范围筛选出某一区间前100个数字，用执行计划分析二者之间的区别，思考速度为什么有区别</li>
</ol>
<div class="language-sql line-numbers-mode" data-highlighter="shiki" data-ext="sql" style="background-color:#282c34;color:#abb2bf"><pre class="shiki one-dark-pro vp-code" v-pre=""><code><span class="line"><span style="color:#C678DD"> SELECT</span><span style="color:#ABB2BF"> id,a,b,c,d </span><span style="color:#C678DD">FROM</span><span style="color:#ABB2BF"> test_table </span><span style="color:#C678DD">WHERE</span><span style="color:#ABB2BF"> B </span><span style="color:#C678DD">BETWEEN</span><span style="color:#D19A66"> 100</span><span style="color:#C678DD"> AND</span><span style="color:#D19A66"> 200</span><span style="color:#C678DD"> LIMIT</span><span style="color:#D19A66"> 100</span><span style="color:#ABB2BF">;</span></span>
<span class="line"><span style="color:#C678DD"> SELECT</span><span style="color:#ABB2BF"> id,a,b,c,d </span><span style="color:#C678DD">FROM</span><span style="color:#ABB2BF"> test_table </span><span style="color:#C678DD">WHERE</span><span style="color:#ABB2BF"> C </span><span style="color:#C678DD">BETWEEN</span><span style="color:#D19A66">  3000000000</span><span style="color:#C678DD"> AND</span><span style="color:#D19A66"> 4000000000</span><span style="color:#C678DD"> LIMIT</span><span style="color:#D19A66"> 100</span><span style="color:#ABB2BF">;</span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div></div></div></div></template>


